Derive every editor mutation through one seam so Escape reaches your core#129
Merged
Conversation
- updateCanvasWidgetTextFromKeyboard now stamps the edit it derives and applies onto the routed event, so the app dispatch hears exactly what the retained editor did — Escape's search-field clear, its composition cancel, and the single-line ArrowUp/Down caret jumps were runtime-only before and never reached the model. - The app-side msgForKeyboard consumes the stamped edit first and keeps its own derivation only as the fallback for events that never crossed the runtime. - The context-menu edit path routes through the same seam and dispatches the stamped event.
- widget-action set_composition/commit_composition/cancel_composition now dispatch the ime gpu input events a live IME session produces: journaled for replay, applied by the editor, and mirrored to the core's on_input — direct editor writes kept the model out of the loop. - set_selection synthesizes the stamped keyboard event the clipboard edits use, so the core's selection mirror follows; it stays un-journaled (no selection input kind exists on the wire). - The accessibility action dispatch and the mobile widget-action ABI funnel through the same verbs, so all three surfaces converge.
- ui_app tests drive a search field through Escape, ArrowUp, ime cancel, and the automation composition/selection verbs, asserting the model mirror and the retained editor agree. - The reference record/replay session types into a search field and Escape-clears it, so replay must re-derive the same clear from the raw journaled events. - Soundboard e2e batteries (Zig live app and transpiled TS core) pin Escape clearing the query and unfiltering the library.
- User-facing story: Escape in a search field now reaches your core, plus the automation composition verbs riding the real input path.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- Suppress event records staged while a journaled widget_accessibility_action dispatch is on the recorder's staging stack: the verb's synthesized key/text/drop children are deterministic derivations the replayed action re-runs, so recording both dispatched every child twice on replay. - Effect results still write through mid-action in feed-then-dispatch order, and event_count/checkpoint ordinals stay coherent with the records a replay reader actually sees. - Pin the class end to end: repeated AX press and set_text plus the composition verbs record and replay with exactly-once input counts and one journal record per action.
- Stage a synthetic widget_accessibility_action inside dispatchCanvasWidgetAccessibilityAction when no platform tag-23 event is on the recorder's staging stack: the direct verb surfaces (embed widgetAction, automation widget_action — now delegated through the same dispatch) journaled only untargeted focus-routed children while the verb's focus write stayed unjournaled, so a first-in-session composition or set_text replayed against the wrong editor or none at all; nested inside a staged platform AX event the synthetic stage is a suppressed placeholder, keeping exactly one record. - Add the composition kinds to the platform WidgetAccessibilityActionKind enum (values 11-13, additive) with both widget_bridge mappings, so the journal and replay's tag-23 arm carry every verb. - Pin the class: composition first-in-session, composition while another field holds focus, and set_text first-in-session all record action-only journals and replay onto their target editor; a recorder mechanics test pins the nested placeholder.
- A CLOSED combobox's ArrowUp/Down are its open keys: the app dispatch resolves the press before any stamped edit, so the caret derivation now yields no edit there and the retained editor agrees with the model mirror; an open picker's arrows already walk into the mounted menu, and an expanded trigger without one keeps the caret jump both sides hear. - Bump the session journal format to v4: this branch serializes the composition action codes 11-13 into accessibility-action records, which a v3 reader would have called corrupt instead of refusing as version skew; the skew message now names the version this build reads, and the skew test pins refusal of older journals too. - Rewrite the journal's stale coverage note: every automation verb journals now (direct-surface verbs as the outer-wins widget_accessibility_action record), so the v1 do-not-journal caveat is gone.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes the launch-round live-smoke finding: pressing Escape in a search field cleared the runtime's text editor visually while the core never heard about it —
model.querydiverged from the screen, the list stayed filtered under an empty field, and the next keystroke dispatched against the stale query.The root cause was architectural: some editor mutations derived core events (typing, paste, the clear button) while others were runtime-local operations that bypassed derivation. Mapping every mutation source found five bypassing paths: Escape-clear, Escape composition-cancel, ArrowUp/Down caret moves on single-line kinds, and the automation/AX composition and selection verbs.
cleararm expresses it — Escape now looks to the core exactly like the clear button always did — so the journal format is untouched and replay reproduces the clear byte-identically (the reference record→replay session now drives an Escape-clear and pins identical model state, fingerprints, and per-frame checkpoints).set_selectionsynthesizes the same stamped keyboard event the context-menu edits use.Flagged for follow-up (design questions, deliberately not implemented here): pointer-placed selection reaching
on_input(needs coalescing), automationset_selectionreplay honesty (needs a wire-level selection input kind), and the raweditCanvasWidgetTexthost API's mirror contract.Suites: validate, test-examples-native, test-ts-core-e2e green;
zig build test's five step-runner noise lines reproduce identically on clean main (every flagged binary passes directly).